package fr.umlv.m2.uwp2011.web.client.professor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTMLTable.ColumnFormatter;
import com.google.gwt.user.client.ui.HTMLTable.RowFormatter;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TabBar;
import com.google.gwt.user.client.ui.VerticalPanel;

import fr.umlv.m2.uwp2011.service.matiere.DisplayMatiere;
import fr.umlv.m2.uwp2011.service.matiere.IMatiereService;
import fr.umlv.m2.uwp2011.service.matiere.IMatiereServiceAsync;
import fr.umlv.m2.uwp2011.service.user.IUserService;
import fr.umlv.m2.uwp2011.service.user.IUserServiceAsync;
import fr.umlv.m2.uwp2011.service.user.UserDTO;
import fr.umlv.m2.uwp2011.web.client.Application;
import fr.umlv.m2.uwp2011.web.client.Session;

/**
 * Defines a page which displays students list for a specified professor.
 *
 */
public class ProfessorStudents extends Composite {

	/**
	 * Tab bar containing list of subjects for a professor.
	 */
	private final TabBar bar;
	
	/**
	 * Header panel containing the tab bar.
	 */
	private final VerticalPanel headerPanel;
	
	/**
	 * Table to display the list of students.
	 */
	private final FlexTable studentsTable;
	
	/**
	 * List of students retrieved from database.
	 */
	private final List<UserDTO> studentsList;
	
	/**
	 * List of subjects retrieved from database.
	 */
	private final List<DisplayMatiere> subjectsList;

	/**
	 * Panel containing the students flex table.
	 */
	private final ScrollPanel bodyPanel;
	
	/**
	 * Main panel of the page.
	 */
	private final VerticalPanel pagePanel;
	
	/**
	 * Root panel of the page.
	 */
	private final VerticalPanel page;

	/**
	 * RPC service used to get students list.
	 */
	private final IUserServiceAsync userService;

	/**
	 * RPC service used to get subjects list.
	 */
	private final IMatiereServiceAsync matiereService;

	/**
	 * Creates a new {@code ProfessorStudents} object.
	 * 
	 * @param session the current session.
	 */
	public ProfessorStudents(final Session session) {
		/*
		 * Initializaing class filds.
		 */
		this.matiereService = GWT.create(IMatiereService.class);
		this.userService = GWT.create(IUserService.class);
		this.subjectsList = new ArrayList<DisplayMatiere>();
		this.studentsList = new ArrayList<UserDTO>();
		
		/*
		 * Getting current user information.
		 */
		UserDTO professor = session.getUser();
		Map<String, String> mapParameters = session.getParameters();
		
		final Long cursus_id = Long.parseLong(mapParameters.get("cursus"));
		
		/*
		 * Widgets creation.
		 */
		this.bar = new TabBar();
		this.headerPanel = new VerticalPanel();
		
		this.studentsTable = new FlexTable();
		this.bodyPanel = new ScrollPanel();
		
		this.pagePanel = new VerticalPanel();
		this.page = new VerticalPanel();
		
		// Getting list of subjects.
		matiereService.getByUserAndCursus(professor.getLogin(), cursus_id, new AsyncCallback<List<DisplayMatiere>>() {
			@Override
			public void onSuccess(List<DisplayMatiere> result) {
				for (DisplayMatiere dm : result) {
					subjectsList.add(dm);
				}
				
				displaySubjectList(cursus_id, session);
			}
			
			@Override
			public void onFailure(Throwable caught) {
				
			}
		});
		
		// Getting list of students.
		userService.getUserByCursusID(cursus_id, new AsyncCallback<List<UserDTO>>() {
			
			@Override
			public void onSuccess(List<UserDTO> result) {
				
				for (UserDTO studentDTO : result) {

					if (studentDTO.isStudent()) {
						studentsList.add(studentDTO);
					}
				}
				
				displayStudentList();
			}
			
			@Override
			public void onFailure(Throwable caught) {
				
			}
		});
		
		initWidgets();
		
	}

	private void displaySubjectList(final long cursus_id, final Session session) {
		for (DisplayMatiere dm : subjectsList) {
			// TODO Changer : Utiliser des anchor pour passer la matiere selectionnee dans session
			Hyperlink link = new Hyperlink(
					dm.getLibelle(),
					Application.PROFESSOR_STUDENTS + "?login=" + session.getParameters().get("login") +
					"&key=" + session.getParameters().get("key") +
					"&cursus=" + cursus_id
			);
			
			bar.addTab(link);
		}
		
	}

	private void initWidgets() {
		/*
		 * Widgtes style.
		 */
		this.page.setWidth("770px");
		
		this.pagePanel.setWidth("745px");
		this.pagePanel.addStyleName("professorStudentsPagePanel");
		
		/*
		 * Page building.
		 */
		this.headerPanel.add(this.bar);
		this.bodyPanel.add(this.studentsTable);
		
		this.pagePanel.add(this.headerPanel);
		this.pagePanel.add(this.bodyPanel);
		
		this.page.add(this.pagePanel);
		this.initWidget(page);
		
	}

	private void displayStudentList() {
		studentsTable.setWidget(0, 0, new Label("Login"));
		studentsTable.setWidget(0, 1, new Label("Nom"));
		studentsTable.setWidget(0, 2, new Label("Prenom"));
		studentsTable.setWidget(0, 3, new Label("E-mail"));
		
		RowFormatter rf = studentsTable.getRowFormatter();
		rf.addStyleName(0, "studentsList-header");
		
		ColumnFormatter cf = studentsTable.getColumnFormatter();
		cf.addStyleName(0, "studentsList-column");
		cf.addStyleName(1, "studentsList-column");
		cf.addStyleName(2, "studentsList-column");
		cf.addStyleName(3, "studentsList-column");
		
		for (int i = 0, column = 0; i < studentsList.size(); i++, column = 0) {
			UserDTO student = studentsList.get(i);
			int row = i + 1;
			// TODO Il faut rajouter le numero etudiant et le groupe dans userDTO.
			
			studentsTable.setWidget(row, column, new Label(student.getLogin()));
			column++;
			
			studentsTable.setWidget(row, column, new Label(student.getLastName()));
			column++;
			
			studentsTable.setWidget(row, column, new Label(student.getGivenName()));
			column++;
			
			studentsTable.setWidget(row, column, new Label(student.getMail()));
		}
		
		studentsTable.setCellPadding(5);
		studentsTable.setCellSpacing(1);
		studentsTable.setBorderWidth(1);

	}
}